import { getTextLength } from './utils'

// 判断碰撞，修改 mark 和 relation 层级信息并返回最大层数
export default function getLevel(marks, relations, tspan, text, scale, left, right) {
  if (!marks) return relations ? 1 : 0

  const levelArr = []
  const markRangeMap = {}

  // 判断重叠分层（跟据字符长度进行粗略估算，在中英文模式下准确，在其他语言下不一定准确）
  marks.forEach(i => {
    // 判断中点是否落在该行
    const start = getTextLength(text.slice(0, tspan.start))
    const end = getTextLength(text.slice(0, tspan.end + 1))
    const iStart = i.start
    const iEnd = i.end
    const center = getTextLength(text.slice(0, iStart)) + getTextLength(text.slice(iStart, iEnd + 1)) / 2
    // 中点不在该行时表示 label 不在该行，不需要多余的层次提升，但需要默认有一级的层次
    if (center <= start || center > end) {
      if (!levelArr[1]) levelArr[1] = []
      return
    }

    // 这一层的起始和结束点
    const width = getTextLength(i.text) * scale
    let lStart = center - start - width / 2
    let lEnd = center - start + width / 2
    // 处理标签出 svg 边界情况
    if (lStart < left) {
      lEnd = lEnd + left - lStart
      lStart = lStart + left - lStart
    }
    if (lEnd > right) {
      lStart = lStart - lEnd + right
      lEnd = lEnd - lEnd + right
    }

    // 储存信息，relations 判断重叠需要用到
    markRangeMap[i.id] = {
      start: lStart,
      end: lEnd
    }

    let level = 1
    while (isOverlap(levelArr[level], lStart, lEnd)) {
      level++
    }
    if (levelArr[level]) {
      levelArr[level].push([lStart, lEnd])
    } else {
      levelArr[level] = [[lStart, lEnd]]
    }
    i.level = level
  })

  // 处理关系分层
  if (relations) {
    relations.forEach(i => {
      const leftLabel = markRangeMap[i.left]
      const rightLabel = markRangeMap[i.right]
      // 文字左右有 3px 空隙，加上倾斜角，增加 2 个字符容错
      const width = getTextLength(i.text) * scale + 2

      let start, end
      // 两个标签都在本行
      if (leftLabel && rightLabel) {
        start = leftLabel.end
        end = rightLabel.start
        i.mode = 'in'
        i.position = 'complete'
        // 标签间距是否够放关联文字
        if (end - start < width) {
          i.mode = 'out'
          start = leftLabel.start
          end = rightLabel.end
          // 此处忽略了头尾超出行需移动的情况，可能会出现误差
          if (end - start < width) {
            const gap = width - end + start
            start = start - gap / 2
            end = end + gap / 2
          }
        }
      }
      // 左标签在本行
      else if (leftLabel) {
        start = leftLabel.end
        end = right
        i.mode = 'in'
        i.position = 'left'
        if (end - start < width) {
          i.mode = 'out'
          start = leftLabel.start
          if (end - start < width) {
            const gap = width - end + start
            start = start - gap
          }
        }
      }
      // 右标签在本行
      else if (rightLabel) {
        start = 0
        end = rightLabel.start
        i.mode = 'in'
        i.position = 'right'
        if (end - start < width) {
          i.mode = 'out'
          end = rightLabel.end
          if (end - start < width) {
            const gap = width - end + start
            end = end + gap
          }
        }
      }
      // 不存在标签
      else if (i.start < tspan.start && i.end > tspan.end) {
        start = 0
        end = right
        i.mode = 'through'
        i.position = 'center'
      }
      // 其他情况不做渲染
      else {
        return
      }

      let level = 1
      while (isOverlap(levelArr[level], start, end)) {
        level++
      }
      if (levelArr[level]) {
        levelArr[level].push([start, end])
      } else {
        levelArr[level] = [[start, end]]
      }
      i.level = level
    })
  }



  return levelArr.length > 0 ? levelArr.length - 1 : 0
}

function isOverlap (arr, start, end) {
  if (!arr) return false
  let flag = false
  arr.find(i => {
    // 0.5 间距容错
    if (start > i[1] + 0.5 || end <= i[0] - 0.5) {
      return false
    } else {
      flag = true
      return true
    }
  })
  return flag
}